
import java.util.concurrent.Semaphore;

public class Database {

    private int readerCount;
    private final Semaphore mutex;
    private final Semaphore db;
    private final Semaphore control;

    public Database() {
        readerCount = 0;
        mutex = new Semaphore(1, true);
        db = new Semaphore(1, true);
        control = new Semaphore(1, true);
    }

    public void startRead() throws InterruptedException {
        control.acquire(); // me aseguro que el escritor no tiene el control
        mutex.acquire();
        readerCount = readerCount + 1;
        if (readerCount == 1) {
            db.acquire();
        }
        mutex.release();
        control.release(); // libero el recurso para los demás lectores
    }

    public void endRead() throws InterruptedException {
        mutex.acquire();
        readerCount = readerCount - 1;
        if (readerCount == 0) {
            db.release();
        }
        mutex.release();
    }

    public void startWrite() throws InterruptedException {
        control.acquire();
        db.acquire();
    }

    public void endWrite() {
        db.release();
        control.release();
    }
}
